/* Muziekfont.java
 * ===============================================
 *
 * History:
 *     2005/21/11 [ws]  Refactored from Ramo beyond recognition, translated...
 *     2005/10/15 [kc]  Source in UTF8 encoding
 *     2004-2005  [bvl] First version (master thesis.)
 *     2004-2005  [wr]  First version (master thesis.)
 */

package org.jfonia.assets.fonts;

import java.awt.Font;
import java.io.InputStream;

/**
 * Helper class providing static methods for rendering based on a musical font (Fughetta)
 * 
 * @author wijnand.schepens@hogent.be
 */
public class MusicFont {
  
    /**
     * Get the string code used for rendering an accidental sign
     * @param type integer denoting type of accidental (-2:double flat, -1:flat, 0:natural, 1:sharp, 2:double sharp)
     * @return string code
     */
    public static String getAccidentalCode(int type) 
    {
        return (type == -2 ? "\uf0ba" :
            type == -1 ? "\uf062" :
                type ==  0 ? "\uf06e" :
                    type ==  1 ? "\uf023" : "\uf0dc");
    }
    
    /**
     * get the width (in "natural" coordinates, i.e. without deriveFont(scale)) of this glyph
     */
    public static double getAccidentalWidth(int type) 
    {
         return (type == -2 ? 3.1 :
            type == -1 ? 1.7 :
                type ==  0 ? 1.3 :
                    type ==  1 ? 1.6 : 1.9);
         // experimentally determined ;-)
    }
    /**
     * Get the string code used for rendering a clef
     * @param cleftype integer denoting the clef type (0:TREBLE, 1:BASS, 2:UT)
     * @return string code
     */
    public static String getClefCode(int cleftype) 
    {
        return (cleftype == 0 ? "\uf026" : 
                    cleftype == 1 ? "\uf03f" : "???");
    }

    public static double getClefWidth(int cleftype) 
    {
         return (cleftype == 0 ? 5.3 : 
                    cleftype == 1 ? 5.7 : 5);
    }

    /**
     * Get the string code used for rendering a notehead (note without stem)
     * @param value integer indicating note value (duration): 1 (whole), 2 (half), 3 (quarter), ...
     * @return string code
     */
    public static String getNoteheadCode(int value) 
    
    {
        return (value == 1 ? "\uf077" :
                    value == 2 ? "\uf0cd" : "\uf0cf");
    }
    
    public static double getNoteheadWidth(int value)
    {
        return (value == 1 ? 3.2 :
                    value == 2 ? 2.6 : 2.3);
    }
    
    /**
     * Get the string code used for rendering a noteflag
     * @param up boolean indicating the direction of the flag. true: flag down (stem up), false: flag up (stem down)
     * @return string code
     */
    public static String getNoteflagCode(boolean stemup) {
        return (stemup ? "\uf06a" : "\uf04a");
    }
    
    public static double getNoteflagWidth(boolean stemup)
    {
        return 2.5;
    }
    
    /**
     * Get the string code used for rendering a rest
     * @param value integer indicating rest value (duration): 1 (whole), 2 (half), 3 (quarter), 4 (eight), ...
     * @return string code
     */
    public static String getRestCode(int value) {
        return (value == 1 ? "\uf0b7" :
            value == 2 ? "\uf0ee" :
                value == 3 ? "\uf0ce" :                        // quarter
                    value == 4 ? "\uf0e4" :                    // eight
                        value == 5 ? "\uf0c5" : "\uf0a8");     // 16th, 32th
    }
    
    public static double getRestWidth(int value)
    {
        return (value == 1 ? 2.3 :
            value == 2 ? 2.3 : 
                value == 3 ? 2.3 :                        
                    value == 4 ? 2.2 :                    
                        value == 5 ? 2.5 : 2.9);     
    }
    
    /**
     * Get the string code used for rendering an augmentation dot
     * @return string code
     */
    public static String getDotCode() {
        return "\uf02E";
    }
    
    /**
     * Get string code used for rendering a positive integer number
     * @param number an integer > 0
     * @return string code
     */
    public static String getNumberCode(int number) {
        StringBuffer sb = new StringBuffer();
        while (number>0)
        {
            sb.append(DIGITCODES[number%10]);
            // TODO: maybe space must be added...   SPACE="\uf0e9"
            number /= 10;
        }
        sb.reverse();
        return sb.toString();
    }
    
      
    
    /**
     * Get the musical font. <p>
     * 
     * If the font hasn't been loaded yet, it is loaded now (from resource).
     * (singleton)<p>
     *
     * Note: use Font.derive(factor) to magnify
     */
    public static Font getFont() throws Exception {
        if (font==null)
            loadFont();
        return font;
    }


    /**
     * music font (Fughetta...)
     */
    private static Font font = null;

    /**
     * codes for digits
     */
    private static final String[] DIGITCODES = 
    {"\uf030", "\uf031", "\uf032",  "\uf033", "\uf034", "\uf035", "\uf036", "\uf037", "\uf038", "\uf039"};
    
    /**
     * load the musicfont
     */
    private static void loadFont() throws Exception {
        InputStream in = (new MusicFont()).getClass().getResourceAsStream("Fughetta.ttf");
        font = Font.createFont(Font.TRUETYPE_FONT,in);
        in.close();
    }

}


